package com.enation.app.javashop.core.goods.service.impl;

import com.alibaba.excel.util.CollectionUtils;
import com.alibaba.fastjson.JSON;
import com.enation.app.javashop.core.base.CachePrefix;
import com.enation.app.javashop.core.base.SettingGroup;
import com.enation.app.javashop.core.base.message.GoodsChangeMsg;
import com.enation.app.javashop.core.base.rabbitmq.AmqpExchange;
import com.enation.app.javashop.core.client.member.MemberCommentClient;
import com.enation.app.javashop.core.client.member.ShopClient;
import com.enation.app.javashop.core.client.system.SettingClient;
import com.enation.app.javashop.core.client.trade.ExchangeGoodsClient;
import com.enation.app.javashop.core.distribution.model.dos.DistributionGoods;
import com.enation.app.javashop.core.distribution.service.DistributionGoodsManager;
import com.enation.app.javashop.core.goods.GoodsErrorCode;
import com.enation.app.javashop.core.goods.model.dos.*;
import com.enation.app.javashop.core.goods.model.dto.ExchangeClientDTO;
import com.enation.app.javashop.core.goods.model.dto.GoodsDTO;
import com.enation.app.javashop.core.goods.model.dto.GoodsSettingVO;
import com.enation.app.javashop.core.goods.model.enums.*;
import com.enation.app.javashop.core.goods.model.vo.*;
import com.enation.app.javashop.core.goods.service.*;
import com.enation.app.javashop.core.goodssearch.util.PinYinUtil;
import com.enation.app.javashop.core.member.model.vo.GoodsGrade;
import com.enation.app.javashop.core.promotion.PromotionErrorCode;
import com.enation.app.javashop.core.promotion.exchange.model.dos.ExchangeDO;
import com.enation.app.javashop.core.promotion.tool.model.dto.PromotionGoodsDTO;
import com.enation.app.javashop.core.shop.model.dos.ShopCatDO;
import com.enation.app.javashop.core.shop.model.enums.ShopStatusEnum;
import com.enation.app.javashop.core.shop.model.vo.ShopCatItem;
import com.enation.app.javashop.core.shop.model.vo.ShopVO;
import com.enation.app.javashop.core.shop.service.ShopCatManager;
import com.enation.app.javashop.core.trade.cart.model.vo.CartSkuVO;
import com.enation.app.javashop.core.trade.cart.model.vo.CartView;
import com.enation.app.javashop.framework.JavashopConfig;
import com.enation.app.javashop.framework.cache.Cache;
import com.enation.app.javashop.framework.context.ThreadContextHolder;
import com.enation.app.javashop.framework.context.UserContext;
import com.enation.app.javashop.framework.database.DaoSupport;
import com.enation.app.javashop.framework.exception.ServiceException;
import com.enation.app.javashop.framework.redis.transactional.RedisTransactional;
import com.enation.app.javashop.framework.security.model.Seller;
import com.enation.app.javashop.framework.util.*;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpSession;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 商品业务类
 *
 * @author fk
 * @version v2.0
 * @since v7.0.0 2018-03-21 11:23:10
 */
@Service
public class GoodsManagerImpl implements GoodsManager {
    protected final Log logger = LogFactory.getLog(this.getClass());

    @Autowired
    @Qualifier("goodsDaoSupport")
    private DaoSupport daoSupport;
    @Autowired
    private GoodsGalleryManager goodsGalleryManager;
    @Autowired
    private GoodsParamsManager goodsParamsManager;
    @Autowired
    private GoodsSkuManager goodsSkuManager;
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private Cache cache;

    @Autowired
    private GoodsQueryManager goodsQueryManager;
    @Autowired
    private SettingClient settingClient;
    @Autowired
    private ExchangeGoodsClient exchangeGoodsClient;
    @Autowired
    private MemberCommentClient memberCommentClient;
    @Autowired
    private ShopClient shopClient;
    @Autowired
    private DistributionGoodsManager distributionGoodsManager;
    @Autowired
    private ShopCatManager shopCatManager;
    @Autowired
    private GoodsQuantityManager goodsQuantityManager;
    @Autowired
    private JavashopConfig javashopConfig;


    @Override
    public GoodsDO add(GoodsDTO goodsVo) {
        GoodsDO goods = addGoods(goodsVo);

        // 发送增加商品消息，店铺增加自身商品数量，静态页使用
        GoodsChangeMsg goodsChangeMsg = new GoodsChangeMsg(new Integer[]{goods.getGoodsId()},
                GoodsChangeMsg.ADD_OPERATION);
        this.amqpTemplate.convertAndSend(AmqpExchange.GOODS_CHANGE, AmqpExchange.GOODS_CHANGE + "_ROUTING", goodsChangeMsg);

        return goods;
    }

    @Transactional(value = "goodsTransactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public GoodsDO addGoods(GoodsDTO goodsVo) {
        // 商城本地化改造 写死商品配送费均由买家承担 BY JFENG
        goodsVo.setGoodsTransfeeCharge(0);
        goodsVo.setMarketEnable(1);

        Seller seller = UserContext.getSeller();
        // 没有规格给这个字段塞0
        goodsVo.setHaveSpec(StringUtil.isNotEmpty(goodsVo.getSkuList()) ? 1 : 0);
        GoodsDO goods = new GoodsDO(goodsVo);

        // 自动生成商品编码
        goods.setSn(PinYinUtil.getPinYinHeadChar(seller.getSellerName())+"_"+ DateUtil.toString(new Date(),"yyyyMMdd") + "_"+((int)(Math.random()*900)+100));

        //判断商品类型
        if (!GoodsType.VIRTUAL.name().equals(goodsVo.getGoodsType())) {
            // 判断是否添加的是积分商品
            if (goodsVo.getExchange() != null && goodsVo.getExchange().getEnableExchange() == 1) {
                if (seller.getSelfOperated() != 1) {
                    throw new ServiceException(GoodsErrorCode.E301.code(), "非自营店铺不能添加积分商品");
                }
                goods.setGoodsType(GoodsType.POINT.name());
            } else {
                goods.setGoodsType(GoodsType.NORMAL.name());
            }
        } else {
            goods.setGoodsType(goodsVo.getGoodsType());
        }


        // 判断是否设置统一价格
        if (goodsVo.getWeight()==null) {
            goodsVo.setWeight(0.0);
        }
        // 判断是否是自营店铺
        goods.setSelfOperated(seller.getSelfOperated() == 1 ? 1 : 0);
        String goodsSettingJson = settingClient.get(SettingGroup.GOODS);

        GoodsSettingVO goodsSetting = JsonUtil.jsonToObject(goodsSettingJson, GoodsSettingVO.class);
        // 判断商品是否需要审核
        goods.setIsAuth(goodsSetting.getMarcketAuth() == 1 ? 0 : 1);
        // 商品状态 是否可用
        goods.setDisabled(1);
        // 商品创建时间
        goods.setCreateTime(DateUtil.getDateline());
        // 商品浏览次数
        goods.setViewCount(0);
        // 商品购买数量
        goods.setBuyCount(0);
        // 评论次数
        goods.setCommentNum(0);
        // 商品评分
        goods.setGrade(100.0);
        // 商品最后更新时间
        goods.setLastModify(DateUtil.getDateline());
        // 商品库存
        goods.setQuantity(goodsVo.getQuantity() == null ? 0 : goodsVo.getQuantity());
        // 可用库存
        goods.setEnableQuantity(goods.getQuantity());
        // 向goods加入图片
        GoodsGalleryDO goodsGalley = goodsGalleryManager
                .getGoodsGallery(goodsVo.getGoodsGalleryList().get(0).getOriginal());
        goods.setOriginal(goodsGalley.getOriginal());
        goods.setBig(goodsGalley.getBig());
        goods.setSmall(goodsGalley.getSmall());
        goods.setThumbnail(goodsGalley.getThumbnail());
        goods.setSellerId(seller.getSellerId());
        goods.setSellerName(seller.getSellerName());
        //如果有规格，则将规格中最低的价格赋值到商品价格中 update by liuyulei  2019-05-21
        if (goods.getHaveSpec() == 1) {
            pushGoodsPrice(goodsVo, goods);
        }
        if(goods.getPrice()==null){
          throw new ServiceException("500","商品价格不能为空!");
        }
        // 商品多分组 shop_cat_items
        ShopCatDO shopCatDO = this.shopCatManager.getModel(goods.getShopCatId());
        if(shopCatDO!=null){
            ShopCatItem shopCatItem = new ShopCatItem();
            BeanUtil.copyProperties(shopCatDO,shopCatItem);
            List<ShopCatItem> shopCatItems = Arrays.asList(shopCatItem);
            goods.setShopCatItems(JSON.toJSONString(shopCatItems));
        }

        // 添加商品
        this.daoSupport.insert(goods);
        // 获取添加商品的商品ID
        Integer goodsId = this.daoSupport.getLastId("es_goods");
        goods.setGoodsId(goodsId);
        // 添加商品参数
        this.goodsParamsManager.addParams(goodsVo.getGoodsParamsList(), goodsId);
        // 添加商品sku信息
        this.goodsSkuManager.add(goodsVo.getSkuList(), goods);
        // 添加相册
        this.goodsGalleryManager.add(goodsVo.getGoodsGalleryList(), goodsId);
        // 添加积分换购商品
        if (goods.getGoodsType().equals(GoodsType.POINT.name())) {
            PromotionGoodsDTO goodsDTO = new PromotionGoodsDTO();
            BeanUtils.copyProperties(goods, goodsDTO);
            ExchangeDO exchange = new ExchangeDO();
            BeanUtils.copyProperties(goodsVo.getExchange(), exchange);
            //校验积分兑换的价格不能高于商品销售价
            if (exchange.getExchangeMoney() > goods.getPrice()) {
                throw new ServiceException(GoodsErrorCode.E301.code(), "积分商品价格不能高于商品原价");
            }
            exchangeGoodsClient.add(new ExchangeClientDTO(exchange, goodsDTO));
        }
        // 佣金比例
        addDistributionGoods(goods);
        return goods;
    }

    private void addDistributionGoods(GoodsDO goods) {
        DistributionGoods distributionGoods = new DistributionGoods();
        distributionGoods.setGrade1Rebate(10D);
        distributionGoods.setGrade2Rebate(2D);
        distributionGoods.setInviterRate(0D);
        distributionGoods.setGoodsId(goods.getGoodsId());
        distributionGoodsManager.edit(distributionGoods);
    }

    @Override
    public GoodsDO edit(GoodsDTO goodsVO, Integer id) {

        GoodsDO goods = editGoods(goodsVO, id);

        // 发送增加商品消息，店铺增加自身商品数量，静态页使用
        GoodsChangeMsg goodsChangeMsg = new GoodsChangeMsg(new Integer[]{id}, GoodsChangeMsg.UPDATE_OPERATION);
        //修改商品时需要删除商品参与的促销活动
        goodsChangeMsg.setDelPromotion(true);
        this.amqpTemplate.convertAndSend(AmqpExchange.GOODS_CHANGE, AmqpExchange.GOODS_CHANGE + "_ROUTING", goodsChangeMsg);

        return goods;
    }

    @Transactional(value = "goodsTransactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public GoodsDO editGoods(GoodsDTO goodsVO, Integer id) {
        Seller seller = UserContext.getSeller();
        GoodsDO goodsDO = goodsQueryManager.getModel(id);
        if (goodsDO == null || !goodsDO.getSellerId().equals(seller.getSellerId())) {
            throw new ServiceException(GoodsErrorCode.E301.code(), "没有操作权限");
        }

        goodsVO.setGoodsId(id);
        GoodsDO goods = new GoodsDO(goodsVO);

        String goodsType=goodsVO.getGoodsType();
        //判断商品类型
        if (!GoodsType.VIRTUAL.name().equals(goodsVO.getGoodsType())) {
            // 判断是否把商品修改成积分商品,自营店
            if (seller.getSelfOperated() == 1) {
                goods.setGoodsType(goodsVO.getExchange() != null && goodsVO.getExchange().getEnableExchange() == 1 ? GoodsType.POINT.name() : GoodsType.NORMAL.name());
            } else {
                goods.setGoodsType(GoodsType.NORMAL.name());
            }
        } else {
            goods.setGoodsType(goodsVO.getGoodsType());
        }

        String goodsSettingJson = settingClient.get(SettingGroup.GOODS);

        // 判断商品修改是否需要审核(前提是该商品上次审核已通过)
        if(goodsDO.getIsAuth()==1){
            GoodsSettingVO goodsSetting = JsonUtil.jsonToObject(goodsSettingJson, GoodsSettingVO.class);
            goods.setIsAuth(goodsSetting.getUpdateAuth() == 1 ? 0 : 1);
        }

        // 添加商品更新时间
        goods.setLastModify(DateUtil.getDateline());
        // 修改相册信息
        List<GoodsGalleryDO> goodsGalleys = goodsVO.getGoodsGalleryList();
        this.goodsGalleryManager.edit(goodsGalleys, goodsVO.getGoodsId());
        // 向goods加入图片
        goods.setOriginal(goodsGalleys.get(0).getOriginal());
        goods.setBig(goodsGalleys.get(0).getBig());
        goods.setSmall(goodsGalleys.get(0).getSmall());
        goods.setThumbnail(goodsGalleys.get(0).getThumbnail());
        goods.setSellerId(seller.getSellerId());
        goods.setSellerName(seller.getSellerName());

        //如果有规格，则将规格中最低的价格赋值到商品价格中 update by liuyulei  2019-05-21
        if (StringUtil.isNotEmpty(goodsVO.getSkuList())) {
            pushGoodsPrice(goodsVO, goods);
        }
        if(goods.getPrice()==null){
            throw new ServiceException("500","商品价格不能为空!");
        }

        // 更新商品
        this.daoSupport.update(goods, id);
        // 如果商品品牌为空，更新商品品牌为空
        if (goods.getBrandId() == null) {
            this.daoSupport.execute("update es_goods set brand_id = null where goods_id = ?", id);
        }
        // 处理参数信息
        this.goodsParamsManager.addParams(goodsVO.getGoodsParamsList(), id);
        // 处理规格信息
        this.goodsSkuManager.edit(goodsVO.getSkuList(), goods);
        // 添加商品的积分换购信息
        PromotionGoodsDTO goodsDTO = new PromotionGoodsDTO();
        BeanUtils.copyProperties(goods, goodsDTO);
        if (goodsVO.getExchange() == null || GoodsType.NORMAL.name().equals(goods.getGoodsType())) {
            exchangeGoodsClient.edit(new ExchangeClientDTO(null, goodsDTO));
        } else {
            ExchangeDO exchange = new ExchangeDO();
            BeanUtils.copyProperties(goodsVO.getExchange(), exchange);
            if (exchange.getExchangeMoney() > goods.getPrice()) {
                throw new ServiceException(GoodsErrorCode.E301.code(), "积分商品价格不能高于商品原价");
            }
            exchangeGoodsClient.edit(new ExchangeClientDTO(exchange, goodsDTO));
        }

        //清除该商品关联的东西
        this.cleanGoodsAssociated(id, goodsVO.getMarketEnable());
        return goods;
    }

    private void pushGoodsPrice(GoodsDTO goodsVO, GoodsDO goods) {
        // 商品价格  =  最低sku价格
        GoodsSkuVO sku = goodsVO.getSkuList().get(0);
        goods.setPrice(sku.getPrice());
        goods.setCost(sku.getCost());
        Double mktprice = sku.getMktprice();
        if(mktprice != null){
            goods.setMktprice(mktprice);
        }
        goods.setWeight(sku.getWeight());

        goodsVO.getSkuList().forEach(skuVo -> {
            if (skuVo.getPrice() < goods.getPrice()) {
                goods.setPrice(skuVo.getPrice());
                goods.setCost(skuVo.getCost());
                goods.setWeight(skuVo.getWeight());
            }
        });
    }


    /**
     * 清除商品的关联<br/>
     * 在商品删除、下架要进行调用
     *
     * @param goodsId
     */
    @Override
    public void cleanGoodsAssociated(int goodsId, Integer markenable) {

        if (logger.isDebugEnabled()) {
            logger.debug("清除goodsid[" + goodsId + "]相关的缓存，包括促销的缓存");
        }

        this.cache.remove(CachePrefix.GOODS.getPrefix() + goodsId);

        // 删除这个商品的sku缓存(必须要在删除库中sku前先删缓存),首先查出商品对应的sku_id
        String sql = "select sku_id from es_goods_sku where goods_id = ?";
        List<Map> skuIds = this.daoSupport.queryForList(sql, goodsId);
        for (Map map : skuIds) {
            cache.remove(CachePrefix.SKU.getPrefix() + map.get("sku_id"));
        }

        //不再读一次缓存竟然清不掉？？所以在这里又读了一下
        this.cache.get(CachePrefix.GOODS.getPrefix() + goodsId);

        //删除该商品关联的活动缓存
        long currTime = DateUtil.getDateline();
        String currDate = DateUtil.toString(currTime, "yyyyMMdd");

        //清除此商品的缓存
        this.cache.remove(CachePrefix.PROMOTION_KEY + currDate + goodsId);

        if (markenable == 0) {
            this.deleteExchange(goodsId);
        }

    }

    @Override
    public void updateGoodsPrice(Integer goodsId, Double price) {
        this.daoSupport.execute("update es_goods set price = ?  where goods_id =? ", price,goodsId);
    }


    /**
     * 删除积分商品
     *
     * @param goodsId
     */
    private void deleteExchange(Integer goodsId) {

        //删除积分商品
        exchangeGoodsClient.del(goodsId);
    }

    @Override
    @RedisTransactional
    @Transactional(value = "goodsTransactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void under(Integer[] goodsIds, String reason, Permission permission) {

        if (reason.length() > 500) {
            throw new ServiceException(PromotionErrorCode.E400.code(), "下架原因长度不能超过500个字符");
        }
        List<Object> term = new ArrayList<>();
        String idStr = SqlUtil.getInSql(goodsIds, term);

        if (Permission.SELLER.equals(permission)) {
            //this.checkPermission(goodsIds, GoodsOperate.UNDER);
            Seller seller = UserContext.getSeller();
            reason = seller==null? "系统下架": "店员" + seller.getUsername() + "下架，原因为：" + reason;
        } else {
            //查看是否是不能下架的状态 
            String sql = "select disabled,market_enable from es_goods where goods_id in (" + idStr + ")";
            List<Map> list = this.daoSupport.queryForList(sql, term.toArray());
            for (Map map : list) {
                Integer disabled = (Integer) map.get("disabled");
                Integer marketEnable = (Integer) map.get("market_enable");
                OperateAllowable operateAllowable = new OperateAllowable(marketEnable, disabled);
                 if (!operateAllowable.getAllowUnder()) {
                     //throw new ServiceException(GoodsErrorCode.E301.code(), "存在不能下架的商品，不能操作");
                 }

            }
            reason = "平台下架，原因为：" + reason;
        }

        term.add(0, reason);
        term.add(1, DateUtil.getDateline());
        String sql = "update es_goods set market_enable = 0,under_message = ?, last_modify=?  where goods_id in (" + idStr + ")";
        this.daoSupport.execute(sql, term.toArray());

        //清除相关的关联
        for (int goodsId : goodsIds) {
            this.cleanGoodsAssociated(goodsId, 0);
        }

        GoodsChangeMsg goodsChangeMsg = new GoodsChangeMsg(goodsIds, GoodsChangeMsg.UNDER_OPERATION, reason);
        this.amqpTemplate.convertAndSend(AmqpExchange.GOODS_CHANGE, AmqpExchange.GOODS_CHANGE + "_ROUTING", goodsChangeMsg);

    }

    @Override
    public void inRecycle(Integer[] goodsIds) {

        this.checkPermission(goodsIds, GoodsOperate.RECYCLE);

        List<Object> term = new ArrayList<>();
        //修改最后修改时间
        term.add(DateUtil.getDateline());
        String idStr = getIdStr(goodsIds, term);
        String sql = "update  es_goods set disabled = 0 ,market_enable=0 , last_modify=?  where goods_id in (" + idStr + ")";
        this.daoSupport.execute(sql, term.toArray());

        //清除相关的关联
        for (int goodsId : goodsIds) {
            this.cleanGoodsAssociated(goodsId, 0);
        }

        GoodsChangeMsg goodsChangeMsg = new GoodsChangeMsg(goodsIds, GoodsChangeMsg.INRECYCLE_OPERATION);
        this.amqpTemplate.convertAndSend(AmqpExchange.GOODS_CHANGE, AmqpExchange.GOODS_CHANGE + "_ROUTING", goodsChangeMsg);

    }

    @Override
    @RedisTransactional
    @Transactional(value = "goodsTransactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void delete(Integer[] goodsIds) {

        this.checkPermission(goodsIds, GoodsOperate.DELETE);

        List<Object> term = new ArrayList<>();
        String idStr = getIdStr(goodsIds, term);
//        String sql = "delete  from es_goods  where goods_id in (" + idStr + ")";
        //修改删除商品的逻辑不做物理删除 add by liuyulei 2019-06-03
        String sql = "update es_goods set disabled = -1  where goods_id in (" + idStr + ")";
        this.daoSupport.execute(sql, term.toArray());
//        // 删除商品sku信息
//        this.goodsSkuManager.delete(goodsIds);
//        // 删除相册信息
//        this.goodsGalleryManager.delete(goodsIds);
        //删除商品发送商品删除消息DEL_OPERATION
        GoodsChangeMsg goodsChangeMsg = new GoodsChangeMsg(goodsIds, GoodsChangeMsg.DEL_OPERATION);
        this.amqpTemplate.convertAndSend(AmqpExchange.GOODS_CHANGE, AmqpExchange.GOODS_CHANGE + "_ROUTING", goodsChangeMsg);
    }

    /**
     * 查看商品是否属于当前登录用户
     *
     * @param goodsIds
     */
    private void checkPermission(Integer[] goodsIds, GoodsOperate goodsOperate) {

        Seller seller = UserContext.getSeller();
        List<Object> term = new ArrayList<>();
        String idStr = SqlUtil.getInSql(goodsIds, term);

        String sql = "select disabled,market_enable from es_goods where goods_id in (" + idStr + ") and seller_id = ?";
        term.add(seller.getSellerId());
        List<Map> list = this.daoSupport.queryForList(sql, term.toArray());
        if (list.size() != goodsIds.length) {
            throw new ServiceException(GoodsErrorCode.E301.code(), "存在不属于您的商品，不能操作");
        }

        // for (Map map : list) {
        //     Integer disabled = (Integer) map.get("disabled");
        //     Integer marketEnable = (Integer) map.get("market_enable");
        //     OperateAllowable operateAllowable = new OperateAllowable(marketEnable, disabled);
        //     switch (goodsOperate) {
        //         case DELETE:
        //             if (!operateAllowable.getAllowDelete()) {
        //                 throw new ServiceException(GoodsErrorCode.E301.code(), "存在不能删除的商品，不能操作");
        //             }
        //             break;
        //         case RECYCLE:
        //             if (!operateAllowable.getAllowRecycle()) {
        //                 throw new ServiceException(GoodsErrorCode.E301.code(), "存在不能放入回收站的商品，不能操作");
        //             }
        //             break;
        //         case REVRET:
        //             if (!operateAllowable.getAllowRevert()) {
        //                 throw new ServiceException(GoodsErrorCode.E301.code(), "存在不能还原的商品，不能操作");
        //             }
        //             break;
        //         case UNDER:
        //             if (!operateAllowable.getAllowUnder()) {
        //                 throw new ServiceException(GoodsErrorCode.E301.code(), "存在不能下架的商品，不能操作");
        //             }
        //             break;
        //         default:
        //             break;
        //     }
        // }

    }

    /**
     * 获取商品id的拼接，且删除缓存中的商品信息
     *
     * @param goodsIds
     * @param term
     * @return
     */
    private String getIdStr(Integer[] goodsIds, List<Object> term) {

        String[] goods = new String[goodsIds.length];
        for (int i = 0; i < goodsIds.length; i++) {
            goods[i] = "?";
            term.add(goodsIds[i]);

        }

        return StringUtil.arrayToString(goods, ",");
    }

    @Override
    public void revert(Integer[] goodsIds) {

        this.checkPermission(goodsIds, GoodsOperate.REVRET);
        List<Object> term = new ArrayList<>();
        String sql = "update  es_goods set disabled = 1  where goods_id in (" + getIdStr(goodsIds, term) + ")";
        this.daoSupport.execute(sql, term.toArray());

        GoodsChangeMsg goodsChangeMsg = new GoodsChangeMsg(goodsIds, GoodsChangeMsg.REVERT_OPERATION);
        this.amqpTemplate.convertAndSend(AmqpExchange.GOODS_CHANGE, AmqpExchange.GOODS_CHANGE + "_ROUTING", goodsChangeMsg);

    }

    @Override
    public void up(Integer goodsId) {

        //查看是否允许上架
        String sql = "select disabled,market_enable,seller_id from es_goods where goods_id = ? limit 1 ";
        Map map = this.daoSupport.queryForMap(sql, goodsId);

        Integer marketEnable = (Integer) map.get("market_enable");
        // 不进行重复上架
        if (marketEnable == 1) {
            return;
        }

        sql = "update es_goods set market_enable = 1 and disabled = 1 where goods_id  = ?";
        this.daoSupport.execute(sql, goodsId);

        cache.remove(CachePrefix.GOODS.getPrefix() + goodsId);

        GoodsChangeMsg goodsChangeMsg = new GoodsChangeMsg(new Integer[]{goodsId}, GoodsChangeMsg.UPDATE_OPERATION);
        this.amqpTemplate.convertAndSend(AmqpExchange.GOODS_CHANGE, AmqpExchange.GOODS_CHANGE + "_ROUTING", goodsChangeMsg);
    }

    @Override
    public void authGoods(Integer goodsId, Integer pass, String message) {

        if (pass == 0 && StringUtil.isEmpty(message)) {
            throw new ServiceException(GoodsErrorCode.E301.code(), "拒绝原因不能为空");
        }

        GoodsDO goods = this.goodsQueryManager.getModel(goodsId);
        if (goods == null) {
            throw new ServiceException(GoodsErrorCode.E301.code(), "无权操作");
        }

        if (goods.getIsAuth() != 0) {
            throw new ServiceException(GoodsErrorCode.E301.code(), "商品已审核，请勿重复审核");
        }

        String sql = "update es_goods set is_auth=?,auth_message=?  where goods_id=? ";
        // 审核通过
        daoSupport.execute(sql, pass == 1 ? 1 : 2, message, goodsId);
        // 发送审核消息
        GoodsChangeMsg goodsChangeMsg = null;
        if (pass == 1) {
            goodsChangeMsg = new GoodsChangeMsg(new Integer[]{goodsId}, GoodsChangeMsg.GOODS_VERIFY_SUCCESS,
                    message);
        } else {
            goodsChangeMsg = new GoodsChangeMsg(new Integer[]{goodsId}, GoodsChangeMsg.GOODS_VERIFY_FAIL,
                    message);
        }
        this.amqpTemplate.convertAndSend(AmqpExchange.GOODS_CHANGE, AmqpExchange.GOODS_CHANGE + "_ROUTING", goodsChangeMsg);
        // 清楚商品的缓存
        cache.remove(CachePrefix.GOODS.getPrefix() + goodsId);
    }


    @Override
    @Transactional(value = "goodsTransactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Integer visitedGoodsNum(Integer goodsId) {
        /**
         * 逻辑：判断当前缓存中的viewedGoods变量是否包含了当前goods，如未，则 向变量中加入goods，如果已经存在则
         * 1、从redis中取出此商品的浏览数 2、如果为空则新增此商品浏览数为1，否则判断浏览数是否大于等于50，逻辑为每50次存入数据库 3、存入相关数据库
         */
        HttpSession session = ThreadContextHolder.getHttpRequest().getSession();
        List<Integer> visitedGoods = (List<Integer>) cache.get(CachePrefix.VISIT_COUNT.getPrefix() + session.getId());
        // 标识此会话是否访问过
        boolean visited = false;
        if (visitedGoods == null) {
            visitedGoods = new ArrayList<Integer>();
        }

        if (visitedGoods.contains(goodsId)) {
            visited = true;
            visitedGoods.remove(goodsId);
        }
        visitedGoods.add(0, goodsId);

        String key = CachePrefix.VISIT_COUNT.getPrefix() + goodsId;
        /** 获取redis中此商品的浏览数 */
        Integer num = (Integer) this.cache.get(key);
        /** 如果redis中未记录此浏览数 则新增此商品浏览数为1 */
        if (num == null) {
            num = 0;
        }

        if (!visited) {

            num++;
            // 如果浏览数大于等于20则存入相关数据库
            if (num >= 20) {
                // num为历史访问量，如果满足条件需要将此次浏览数也要加进去 固+1
                this.daoSupport.execute("update es_goods set view_count = view_count + ? where goods_id = ?", num, goodsId);
                num = 0;
            }
            this.cache.put(key, num);
        }

        return num;
    }

    /**
     * 获取新赠商品
     *
     * @param length
     * @return
     */
    @Override
    public List<BackendGoodsVO> newGoods(Integer length) {
        return this.daoSupport.queryForList("select * from es_goods where market_enable = 1 and disabled = 1 order by create_time desc limit 0, ?", BackendGoodsVO.class, length);
    }


    @Override
    public void underShopGoods(Integer sellerId) {

        String sql = "update es_goods set market_enable = 0 where seller_id = ? ";
        this.daoSupport.execute(sql, sellerId);
        //发送商品下架消息
        sql = "select goods_id from es_goods where seller_id = ?";
        List<Map> list = this.daoSupport.queryForList(sql, sellerId);
        Integer[] goodsIds = new Integer[list.size()];
        int i = 0;
        if (StringUtil.isNotEmpty(list)) {
            for (Map map : list) {
                goodsIds[i] = StringUtil.toInt(map.get("goods_id").toString(), false);
                i++;
            }

            GoodsChangeMsg goodsChangeMsg = new GoodsChangeMsg(goodsIds, GoodsChangeMsg.UNDER_OPERATION, "店铺关闭");
            this.amqpTemplate.convertAndSend(AmqpExchange.GOODS_CHANGE, AmqpExchange.GOODS_CHANGE + "_ROUTING", goodsChangeMsg);

        }

    }

    @Override
    public void updateGoodsGrade() {

        List<GoodsGrade> list = this.memberCommentClient.queryGoodsGrade();

        if (StringUtil.isNotEmpty(list)) {
            for (GoodsGrade goods : list) {
                String updateSql = "update es_goods set grade=? where goods_id=?";
                double grade = CurrencyUtil.mul(goods.getGoodRate(), 100);
                this.daoSupport.execute(updateSql, CurrencyUtil.round(grade, 1), goods.getGoodsId());
                cache.put(CachePrefix.GOODS_GRADE.getPrefix() + goods.getGoodsId(), CurrencyUtil.round(grade, 1));
                // 发送商品消息变化消息
                GoodsChangeMsg goodsChangeMsg = new GoodsChangeMsg(new Integer[]{goods.getGoodsId()},
                        GoodsChangeMsg.UPDATE_OPERATION);
                this.amqpTemplate.convertAndSend(AmqpExchange.GOODS_CHANGE, AmqpExchange.GOODS_CHANGE + "_ROUTING", goodsChangeMsg);
            }
        }


    }

    /**
     * 获取商品是否使用检测的模版
     *
     * @param templateId
     * @return 商品
     */
    @Override
    public GoodsDO checkShipTemplate(Integer templateId) {
        List<GoodsDO> goodsDOS = this.daoSupport.queryForList("select * from es_goods where template_id = ?", GoodsDO.class, templateId);
        if (goodsDOS != null && goodsDOS.size() > 0) {
            return goodsDOS.get(0);
        }
        return null;
    }

    /**
     * 修改某店铺商品店铺名称
     *
     * @param sellerId
     * @param sellerName
     */
    @Override
    public void changeSellerName(Integer sellerId, String sellerName) {
        this.daoSupport.execute("update es_goods set seller_name = ? where seller_id = ?", sellerName, sellerId);
        this.daoSupport.execute("update es_goods_sku set seller_name = ? where seller_id = ?", sellerName, sellerId);

        this.getAll(sellerId).forEach(goodsDO -> {
            this.cache.remove(CachePrefix.GOODS.getPrefix() + goodsDO.getGoodsId());
        });
        this.getAllSku(sellerId).forEach(skuDO -> {
            this.cache.remove(CachePrefix.SKU.getPrefix() + skuDO.getSkuId());
        });
    }


    private List<GoodsDO> getAll(Integer sellerId) {
        return this.daoSupport.queryForList("select * from es_goods where seller_id = ?", GoodsDO.class, sellerId);
    }

    private List<GoodsSkuDO> getAllSku(Integer sellerId) {
        return this.daoSupport.queryForList("select * from es_goods_sku where seller_id = ?", GoodsSkuDO.class, sellerId);
    }

    @Override
    public void updateGoodsType(Integer sellerId, String type) {
        this.daoSupport.execute("update es_goods set goods_type=? where seller_id = ?", type, sellerId);

    }

    @Override
    @Transactional(value = "goodsTransactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void updatePriority(Integer goodsId, Integer priority) {
        this.daoSupport.execute("update es_goods set priority = ? where goods_id = ? ", priority, goodsId);
        // 发送修改商品优先级消息
        GoodsChangeMsg goodsChangeMsg = new GoodsChangeMsg(new Integer[]{goodsId}, GoodsChangeMsg.GOODS_PRIORITY_CHANGE);
        this.amqpTemplate.convertAndSend(AmqpExchange.GOODS_PRIORITY_CHANGE, AmqpExchange.GOODS_PRIORITY_CHANGE + "_ROUTING", goodsChangeMsg);
    }

    /**
     * @author john  2020-5-13
     * @param sellerId
     * @param goodsIds
     */
    @Override
    public void ups(Integer sellerId, Integer[] goodsIds) {
        for(Integer goodsId : goodsIds ){
            this.up(goodsId);
        }

    }

    @Override
    public List<CategoryCountVO> countByCategoryId() {
        List<CategoryCountVO> list = this.daoSupport.queryForList("select count(*) count ,category_id categoryId from es_goods group by category_id", CategoryCountVO.class);
        return list;
    }

    @Override
    public void batchUpdateGoods(List<GoodsDO> updateGoods) {
        for (GoodsDO updateGood : updateGoods) {
            this.daoSupport.execute("update es_goods set category_id=? ,shop_cat_id=?  where goods_id = ?", updateGood.getCategoryId(), updateGood.getShopCatId(),updateGood.getGoodsId());
        }
        Integer[] goodsIds = updateGoods.stream().map(GoodsDO::getGoodsId).collect(Collectors.toList()).toArray(new Integer[0]);
        GoodsChangeMsg goodsChangeMsg = new GoodsChangeMsg(goodsIds, GoodsChangeMsg.REVERT_OPERATION);
        this.amqpTemplate.convertAndSend(AmqpExchange.GOODS_CHANGE, AmqpExchange.GOODS_CHANGE + "_ROUTING", goodsChangeMsg);
    }

    @Override
    public GoodsDO getByUpGoodsId(String upGoodsId) {
        String sql = "select goods_id,up_goods_id,goods_name,seller_id from es_goods where up_goods_id = ?";
        GoodsDO goodsDO = this.daoSupport.queryForObject(sql, GoodsDO.class, upGoodsId);
        return goodsDO;
    }

    @Override
    public GoodsDO getByGoodsId(Integer goodsId) {
        String sql = "select goods_id,up_goods_id,goods_name,seller_id from es_goods where goods_id = ?";
        GoodsDO goodsDO = this.daoSupport.queryForObject(sql, GoodsDO.class, goodsId);
        return goodsDO;
    }

    @Override
    public void updateGoodsShopCat(Integer goodsId,  List<ShopCatItem> shopCatList){
        this.daoSupport.execute("update es_goods set shop_cat_id = ?, shop_cat_items = ? where goods_id = ? ",shopCatList.get(0).getShopCatId(), JSON.toJSONString(shopCatList), goodsId);
        // 发送修改商品消息
        GoodsChangeMsg goodsChangeMsg = new GoodsChangeMsg(new Integer[]{goodsId}, GoodsChangeMsg.GOODS_PRIORITY_CHANGE);
        this.amqpTemplate.convertAndSend(AmqpExchange.GOODS_PRIORITY_CHANGE, AmqpExchange.GOODS_PRIORITY_CHANGE + "_ROUTING", goodsChangeMsg);
    }

    //根据上游商品id查询商品列表
    @Override
    public List<GoodsDO> getListByUpGoodsIds(String[] upGoodsIds) {
        String idsString = StringUtil.arrayToString(upGoodsIds,",");
        String sql = "select goods_id,up_goods_id,goods_name,seller_id from es_goods where up_goods_id in ("+idsString+")";
        List<GoodsDO> goodsDOList=this.daoSupport.queryForList(sql,GoodsDO.class);
        return goodsDOList;
    }

    // 判断是否包含虚拟商品，如果是虚拟商品则不需要收货地址或者计算运费
    @Override
    public Boolean checkVirtualGoods(CartView cartView) {
        boolean isVirtual = false;
        if (!org.springframework.util.CollectionUtils.isEmpty(cartView.getCartList())) {
            List<CartSkuVO> skuVOList = cartView.getCartList().get(0).getSkuList();
            if (!org.springframework.util.CollectionUtils.isEmpty(skuVOList)) {
                skuVOList = skuVOList.stream().filter(sku -> GoodsType.VIRTUAL.name().equals(sku.getGoodsType())).collect(Collectors.toList());
                if (!org.springframework.util.CollectionUtils.isEmpty(skuVOList) && skuVOList.size() == 1) {
                    isVirtual = true;
                }
            }
        }
        return isVirtual;
    }


    //复制商品到目标店铺
    @Override
    @Transactional(value = "goodsTransactionManager", propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public CopyGoodsResult copyGoods(String goodsIdsString, Integer sellerId) {
        /*
         * 1、检查店铺是否营业， 未营业就抛异常
         * 2、查询复制商品信息
         * 3、查询目标店铺的分类信息
         * 4、检查目标店铺是否包含复制的商品分类 没有分类抛异常
         * 5、复制商品 es_goods es_goods_sku 更新es的信息 es_specification es_spec_values es_category_spec
         *  如果商品没有规格，把原来的sku中的id,seller_id,seller_name改成现在的就可以；
         *  如果商品有规格，则需要把保存规格信息；
         * es_goods：修改商品的seller_id,seller_name，创建时间，last_modify，shop_cat_id=null,shop_cat_items=null
         * es_goods_sku:goods_id,specs(规格信息)，seller_id，seller_name，hash_code
         * es_specification：seller_id
         * es_spec_values：seller_id，spec_id
         * es_category_spec：category_id，spec_id
         */

        if (StringUtil.isEmpty(goodsIdsString)) {
            return new CopyGoodsResult(ResultCodeEnum.E601.getCode(), ResultCodeEnum.E601.getDescription());
        }

        //1、检查店铺是否启用
        String shopSql = "select s.member_id,s.member_name,s.shop_name,s.shop_disable,s.shop_createtime,s.shop_endtime,d.* from es_shop s left join es_shop_detail d on  s.shop_id = d.shop_id where s.shop_id = ?";
        ShopVO shopVO = this.daoSupport.queryForObject(shopSql, ShopVO.class, sellerId);
        if (!ShopStatusEnum.OPEN.value().equals(shopVO.getShopDisable())) {
            return new CopyGoodsResult(ResultCodeEnum.E602.getCode(), ResultCodeEnum.E602.getDescription());
        }

        //检查目标店铺经营的类目
        String GoodsManagementCategoryString = shopVO.getGoodsManagementCategory();
        if (StringUtil.isEmpty(GoodsManagementCategoryString)) {
            return new CopyGoodsResult(ResultCodeEnum.E603.getCode(), ResultCodeEnum.E603.getDescription());
        }

        //2、获取需要复制的商品
        String goodsSql = "select * from es_goods where goods_id in (" + goodsIdsString + ")";
        List<GoodsDO> originalGoodsDOList = this.daoSupport.queryForList(goodsSql, GoodsDO.class);

        //3、判断目标店铺是否有复制商品的分类

        //需要复制的商品类目
        List<Integer> originalGoodsCategoryIdList = originalGoodsDOList.stream().map(GoodsDO::getCategoryId).collect(Collectors.toList());

        //查询需要复制的商品类目的顶级类目
        String categoryIds = StringUtil.listToString(originalGoodsCategoryIdList, ",");
        String sql = "SELECT c.* FROM (SELECT if(c.parent_id = 0, c.category_id, c.parent_id) AS two_parent_id FROM (SELECT if(c.parent_id = 0, c.category_id, c.parent_id) AS three_parent_id FROM es_category c " +
                "WHERE c.category_id in (" + categoryIds + ") GROUP BY three_parent_id) tmp LEFT JOIN es_category c ON c.category_id = tmp.three_parent_id GROUP BY two_parent_id) tmp2 " +
                "LEFT JOIN es_category c ON c.category_id = tmp2.two_parent_id;";
        List<CategoryDO> MaxCategoryIdList = this.daoSupport.queryForList(sql, CategoryDO.class);

        //目标店铺经营的类目
        List<String> GoodsManagementCategoryList = Arrays.asList(GoodsManagementCategoryString.split(","));

        //保存目标店铺没有的分类
        List<Integer> shopNoCategory = new ArrayList<>();
        for (CategoryDO category : MaxCategoryIdList) {
            Integer categoryId = category.getCategoryId();
            if (!GoodsManagementCategoryList.contains(categoryId.toString())) {
                shopNoCategory.add(categoryId);
            }
        }

        //4、目标店铺没有 复制商品 的分类，返回提示没有哪些分类
        if (!CollectionUtils.isEmpty(shopNoCategory)) {
            String CategoryIdsString = StringUtil.arrayToString(shopNoCategory.toArray(), ",");
            String categorySql = "select * from es_category where category_id in (" + CategoryIdsString + ")";
            List<CategoryDO> categoryDOList = this.daoSupport.queryForList(categorySql, CategoryDO.class);
            List<String> categoryNameList = categoryDOList.stream().map(CategoryDO::getName).collect(Collectors.toList());
            String categoryNameString = StringUtil.arrayToString(categoryNameList.toArray(), ",");
            return new CopyGoodsResult(ResultCodeEnum.E604.getCode(), ResultCodeEnum.E604.getDescription() + "：" + categoryNameString);
        }

        //---------开始商品复制--------

        String sellerName = shopVO.getShopName();
        //5、获取所有需要复制的商品SKU信息
        String goodsSkuSql = "select * from es_goods_sku where goods_id in (" + goodsIdsString + ")";
        List<GoodsSkuDO> originalGoodsSkuDOList = this.daoSupport.queryForList(goodsSkuSql, GoodsSkuDO.class);

        //获取所有需要复制的商品相册信息
        Map<Integer, List<GoodsGalleryDO>> goodsGalleryMap = this.goodsGalleryManager.getGoodsGallersByGoodsIds((Integer[]) ConvertUtils.convert(goodsIdsString.split(","), Integer.class));

        //需要保存的商品相册信息
        List<GoodsGalleryDO> needAddGalleryList = new ArrayList<>();
        //保存发送mq消息的商品ID
        List<Integer> mqGoodsIds = new ArrayList<>();
        //需要保存的所有sku
        List<GoodsSkuDO> newSkuList = new ArrayList<>();

        // 6、循环复制商品
        for (GoodsDO originalGoods : originalGoodsDOList) {
            if (originalGoods.getSellerId().equals(sellerId)) {
                //如果当前店铺已经有这个商品，则在原商品名后面加副本
                originalGoods.setGoodsName(originalGoods.getGoodsName().concat("副本"));
            }
            Integer originalGoodsId = originalGoods.getGoodsId();
            //Ⅰ、新增商品
            originalGoods.setGoodsId(null);
            originalGoods.setSellerId(sellerId);
            originalGoods.setSellerName(sellerName);
            //默认商品是下架状态
            originalGoods.setMarketEnable(0);
            originalGoods.setCreateTime(DateUtil.getDateline());
            originalGoods.setLastModify(DateUtil.getDateline());
            originalGoods.setShopCatId(null);
            originalGoods.setShopCatItems(null);
            this.daoSupport.insert(originalGoods);


            // 获取添加商品的商品ID
            Integer goodsId = this.daoSupport.getLastId("es_goods");
            mqGoodsIds.add(goodsId);

            //Ⅱ、保存商品相册信息（批量保存）
            List<GoodsGalleryDO> goodsGalleryDOList = goodsGalleryMap.get(originalGoodsId);
            if(!CollectionUtils.isEmpty(goodsGalleryDOList)){
                goodsGalleryDOList.forEach(goodsGalleryDO -> goodsGalleryDO.setGoodsId(goodsId));
                needAddGalleryList.addAll(goodsGalleryDOList);
            }

            //获取当前商品的所有SKU
            List<GoodsSkuDO> originalSkuList = originalGoodsSkuDOList.stream().filter(goodsSkuDO -> goodsSkuDO.getGoodsId().equals(originalGoodsId)).collect(Collectors.toList());

            if (!CollectionUtils.isEmpty(originalSkuList)) {
                //已经保存过的规格名
                List<SpecificationDO> specificationDOList = new ArrayList<>();
                //Ⅲ、保存规格信息
                for (GoodsSkuDO goodsSkuDO : originalSkuList) {
                    //商品分类ID
                    Integer categoryId = goodsSkuDO.getCategoryId();

                    //a、商品的规格信息，如果商品有规格，则需要把保存规格信息
                    String specsString = goodsSkuDO.getSpecs();
                    if (StringUtil.isEmpty(specsString)) {
                        continue;
                    }

                    //原来的商品规格信息
                    List<SpecValueVO> oldSpecValueVOList = JsonUtil.jsonToList(specsString, SpecValueVO.class);

                    //需要保存的规格值信息
                    List<SpecValueVO> newSpecValueVOList = new ArrayList<>();
                    for (SpecValueVO specValueVO : oldSpecValueVOList) {
                        //判断需不需要新增规格名
                        boolean insertStatus = false;
                        Integer specId = 0;
                        //如果没有保存过规格名就新增，如果保存过就给specId赋值
                        if (!CollectionUtils.isEmpty(specificationDOList)) {
                            List<SpecificationDO> specFilterDOList = specificationDOList.stream().filter(specificationDO -> specificationDO.getSpecName().equals(specValueVO.getSpecName())).collect(Collectors.toList());
                            if (CollectionUtils.isEmpty(specFilterDOList)) {
                                insertStatus = true;
                            } else {
                                specId = specFilterDOList.get(0).getSpecId();
                            }
                        } else {
                            insertStatus = true;
                        }

                        //4、保存规格名信息
                        if (insertStatus) {
                            SpecificationDO specificationDO = new SpecificationDO();
                            specificationDO.setSpecName(specValueVO.getSpecName());
                            specificationDO.setDisabled(1);
                            specificationDO.setSellerId(sellerId);
                            specificationDO.setSpecMemo("商家自定义");

                            //添加规格名
                            this.daoSupport.insert(specificationDO);
                            specId = this.daoSupport.getLastId("es_specification");
                            specificationDO.setSpecId(specId);
                            specificationDOList.add(specificationDO);
                        }

                        //5、添加规格值
                        SpecValuesDO specValuesDO = new SpecValuesDO();
                        specValuesDO.setSellerId(sellerId);
                        specValuesDO.setSpecId(specId);
                        specValuesDO.setSpecValue(specValueVO.getSpecValue());
                        specValuesDO.setSpecName(specValueVO.getSpecName());
                        this.daoSupport.insert(specValuesDO);
                        Integer specValueId = this.daoSupport.getLastId("es_spec_values");


                        //6、保存分类规格的关系
                        CategorySpecDO categorySpec = new CategorySpecDO(categoryId, specId);
                        this.daoSupport.insert(categorySpec);

                        specValueVO.setSpecId(specId);
                        specValueVO.setSpecValueId(specValueId);
                        newSpecValueVOList.add(specValueVO);
                    }
                    goodsSkuDO.setSpecs(JsonUtil.objectToJson(newSpecValueVOList));
                    int hashCode = buildHashCode(newSpecValueVOList);
                    goodsSkuDO.setHashCode(hashCode);


                    //6、封装sku信息
                    goodsSkuDO.setSkuId(null);
                    goodsSkuDO.setGoodsId(goodsId);
                    goodsSkuDO.setSellerId(sellerId);
                    goodsSkuDO.setSellerName(sellerName);
                    newSkuList.add(goodsSkuDO);
                }
                if (!CollectionUtils.isEmpty(newSkuList)) {
                    //Ⅳ、批量添加商品sku
                    this.daoSupport.batchInsert("es_goods_sku", newSkuList);

                }
            }

        }

        //7、批量添加商品相册
        if (!CollectionUtils.isEmpty(needAddGalleryList)) {
            this.daoSupport.batchInsert("es_goods_gallery", needAddGalleryList);
        }


        if (!CollectionUtils.isEmpty(mqGoodsIds)) {
            String allSkuSql = "select * from es_goods_sku where goods_id in ( " + StringUtil.listToString(mqGoodsIds, ",") + ")";
            newSkuList = this.daoSupport.queryForList(allSkuSql, GoodsSkuDO.class);
            //Ⅴ、为新增的sku增加库存
            if (!CollectionUtils.isEmpty(newSkuList))
                goodsSkuManager.updateStock(newSkuList);

            // 8、、发送增加商品消息
            GoodsChangeMsg goodsChangeMsg = new GoodsChangeMsg(mqGoodsIds.toArray(new Integer[mqGoodsIds.size()]),
                    GoodsChangeMsg.ADD_OPERATION);
            this.amqpTemplate.convertAndSend(AmqpExchange.GOODS_CHANGE, AmqpExchange.GOODS_CHANGE + "_ROUTING", goodsChangeMsg);
        }


        return CopyGoodsResult.success(null);
    }

    private int buildHashCode(List<SpecValueVO> specValueVOList) {
        HashCodeBuilder codeBuilder = new HashCodeBuilder(17, 37);
        specValueVOList.forEach(specValueVO -> {
            String specValue = specValueVO.getSpecValue();
            codeBuilder.append(specValue);

        });
        int hashCode = codeBuilder.toHashCode();

        return hashCode;
    }

}

